package jgcp.message;

import java.io.Serializable;

import jgcp.utils.ByteUtil;

/**
 * Message class represents a message which can be send and receive over the
 * network. <br>
 * <p>
 * The format of a message is defined as below:<br>
 * Message Type(Integer,4 bytes)|Message Body Length(Integer,4 bytes)|Message Body(a
 * string)
 * </p>
 * 
 * @author Jie Zhao(288654)
 * 
 */
public class Message implements Serializable {

	private final static int HEADSIZE = (Integer.SIZE / Byte.SIZE)*2;
	private int type = MessageType.HEARTBEAT;
	private int bodyLength = 0;
	private String messageBody = "";

	public Message() {
	}

	public Message(int type, String message) {
		this.type = type;
		this.messageBody = message;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public String getMessageBody() {
		return messageBody;
	}

	public void setMessageBody(String msgBody) {
		this.messageBody = msgBody;
	}

	/**
	 * Parse a byte array to a message
	 * 
	 * @param data
	 * @return
	 */
	public static Message parseMessage(byte[] data) {
		Message result = new Message();
		if (data != null) {
			result.type = ByteUtil.parseInt(data, 0);
			result.bodyLength = ByteUtil.parseInt(data, 4);
			result.messageBody = new String(data, HEADSIZE, result.bodyLength);
		}
		return result;
	}

	/**
	 * Convert a message to a byte array then it can be send over the internet.
	 * 
	 * @return
	 */
	public byte[] toByteArray() {
		byte[] message = messageBody.getBytes();
		byte[] result = new byte[HEADSIZE + message.length];

		ByteUtil.fillByInt(result, 0, this.type);
		bodyLength = message.length;
		ByteUtil.fillByInt(result, 4, bodyLength);
		for (int i = 0; i < message.length; i++) {
			result[i + HEADSIZE] = message[i];
		}
		return result;
	}

	@Override
	public String toString() {
		return "Message Type:" + type + " Message Length:" + bodyLength
				+ " Message:" + messageBody;
	}

	public static void main(String[] args) {
		Message m = new Message();
		m.setType(MessageType.HEARTBEAT);
		StringBuffer sb = new StringBuffer();
		sb.append("Hello World!");

		m.setMessageBody(sb.toString());
		System.out.println(m.getMessageBody());
		ByteUtil.printByteArray(m.toByteArray());
	}
}
